package dimension.starry.mixin;

import dimension.starry.event.Events;
import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.damage.DamageSource;
import net.minecraft.nbt.NbtCompound;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.ModifyVariable;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;

import java.math.BigDecimal;

@Mixin(value = {LivingEntity.class}, priority = 1001)
public abstract class LivingEntityMixin {

    @Inject(method = "onDeath(Lnet/minecraft/entity/damage/DamageSource;)V", at = @At(value = "HEAD"),
        cancellable = true)
    public void livingEntityDie(DamageSource damageSource, CallbackInfo ci) {
        LivingEntity entity = (LivingEntity) (Object) this;
        if (!Events.LIVING_ENTITY_DEATH_EVENT.invoker().onDeath(entity, damageSource)) {
            ci.cancel();
        }
    }

    @ModifyVariable(
        method = "applyDamage",
        at = @At(value = "INVOKE_ASSIGN", target = "Ljava/lang/Math;max(FF)F", ordinal = 0),
        ordinal = 0,
        argsOnly = true
    )
    private float livingEntityActuallyHurt(float f, DamageSource damageSource, float damage) {
        LivingEntity livingEntity = (LivingEntity) (Object) this;
        float newDamage = Events.LIVING_DAMAGE_CALC_EVENT.invoker().onLivingDamageCalc(livingEntity, damageSource, f);
        if (newDamage != -1 && !new BigDecimal(newDamage).equals(new BigDecimal(f))) {
            return newDamage;
        }
        return f;
    }

    @Inject(method = "damage(Lnet/minecraft/entity/damage/DamageSource;F)Z", at = @At(value = "HEAD"))
    public void livingEntityHurt(DamageSource source, float amount, CallbackInfoReturnable<Boolean> cir) {
        LivingEntity livingEntity = (LivingEntity) (Object) this;
        Events.LIVING_DAMAGE_EVENT.invoker().onLivingDamage(livingEntity, source, amount);
    }

}

